package model.user;

import core.Database;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.apache.log4j.Logger;

/**
 * Represents the session of current user.
 * This JSF bean is Session Scoped, and it's life time depends on user's activity 
 * and server configuration (see session-timeout parameter in web.xml)
 * @author Danon
 */
@ManagedBean
@SessionScoped
public class UserSessionBean implements Serializable {

    private UserProfileBean user;
    private boolean loggedIn;
    
    private static final Logger logger = Logger.getLogger(UserSessionBean.class);
    
    /** Creates a new instance of UserSessionBean */
    public UserSessionBean() {
    }

    public boolean isLoggedIn() {
        return loggedIn;
    }
    
    /**
     * Returns a current user who corresponds to this session.
     */
    public UserProfileBean getUser() {
        return user;
    }
    
    /**
     * Performs authentication of user
     * @param u UserBean to log in
     * @return "welcome" if all is OK, and logOut() otherwise 
     */
    public String logIn(UserProfileBean u) {
        if(u == null) 
            return logOut();
        user = u;
        
        try {
            Connection c = Database.getInstance().getConnection();
            try (PreparedStatement ps = c.prepareStatement("select user_id, login, full_name "
                         + "from users where login = ? and password = ?")) {
                ps.setString(1, u.getLogin());
                ps.setString(2, u.getPassword());
                ResultSet rs = ps.executeQuery();
                if(rs.next()) {
                    user.setId(rs.getInt("user_id"));
                    user.setLogin(rs.getString("login"));
                    user.setFullName(rs.getString("full_name"));
                    user.setPassword(null);
                    loggedIn = true;
                }
                rs.close();
            }
            if(!loggedIn) {
                logger.info("Log in failed for user "+u.getLogin()+". Incorrect login/passord.");
                return logOut();
            }
        } catch (Exception ex) {
            logger.debug("Database problem: "+ex.getMessage());
            return logOut();
        }
        logger.info("User logged in: "+u.getLogin()+".");
        return "welcome?faces-redirect=true";
    }
    
    public String logOut() {
        if(user!=null)
            logger.info("User logged out: "+user.getLogin());
        loggedIn = false;
        user = null;
        return "login?faces-redirect=true";
    }
    
    /** Adds user to database and redirects to login page */
    public String signUp(UserProfileBean u) {
        if(u == null) 
            return "signup?faces-redirect=true";
        try {
            Connection c = Database.getInstance().getConnection();
            try (PreparedStatement ps = c.prepareStatement("insert into users (user_id, login, password, full_name) "
                         + "values (gen_user_id.nextval, ?, ?, ?)")) {
                ps.setString(1, u.getLogin());
                ps.setString(2, u.getPassword());
                ps.setString(3, u.getFullName());
                ps.executeUpdate();
            }
        } catch (Exception ex) {
            logger.debug("Signup failed: user = "+u.getLogin(),ex);
            return "signup?faces-redirect=true";
        }
        return "login?faces-redirect=true";
    }
}
